﻿#include "../header/Control.h"
#include <QtWidgets/QMainWindow>
#include <Windows.h>
#include <windowsx.h>
# pragma execution_character_set("utf-8")
BeControl::BeControl(QHostAddress _ip)
{
	cli = new QTcpSocket(this);
	cli->connectToHost(_ip, PORT);
	connect(cli, SIGNAL(connected()), this, SLOT(ConnectedToServer()));     //连接成功
	connect(cli, SIGNAL(readyRead()), this, SLOT(Receive()));     //读取服务器信息数据
	connect(cli, SIGNAL(disconnected()), this, SLOT(Disconnected()));       //服务器断开
	connect(cli, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(Error(QAbstractSocket::SocketError)));     //出错函数
	qDebug() << "受控端已经启动，服务端" << _ip << ":" << PORT << endl;

}
void BeControl::ConnectedToServer()
{
	qDebug() << "控制：已连接至服务器";
}
void BeControl::Disconnected()
{
	qDebug() << "控制服务器已经退出";
}
BeControl::~BeControl()
{
	qDebug() << "被控制函数退出" << endl;
}
void BeControl::Error(QAbstractSocket::SocketError err)
{
	qDebug() << "受控端出错" << err << endl;
}
void BeControl::Receive()
{
	QTcpSocket* client = (QTcpSocket*)this->sender();      //强转TCP类型
	QString msg;
	while (!client->atEnd())     //不到末尾进行读取内容
	{
		msg.append(QString(client->readAll()));
	}
	istringstream iss(msg.toStdString());
	string type, ope, param;
	while (iss >> type >> ope >> param)
	{
		if (type == "end")
		{
			cli->close();
		}
		//cout << type << " " << ope << " " << param << endl;
		if (type == "keyboard")//键盘事件
		{
			keybd_event(atoi(param.data()), 0, ope == "up" ? KEYEVENTF_KEYUP : 0, 0);//模拟按键按下
		}
		else if (type == "mouseclick")//鼠标单击
		{
			if (ope == "up")
			{
				if (param == "left")
				{
					mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
				}
				else
				{
					mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0);
				}
			}
			else if (ope == "down")
			{
				if (param == "left")
				{
					mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
				}
				else
				{
					mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0);
				}
			}
		}
		else if (type == "mousewheel")//鼠标滚轮事件
		{
			if (ope == "move")
			{
				int dis = atoi(param.data());
				mouse_event(MOUSEEVENTF_WHEEL, 0, 0, dis, 0);
			}

		}
		else if (type == "mousemove")
		{
			string y;
			iss >> y;
			int dx = atoi(param.data()), dy = atoi(y.data());
			mouse_event(MOUSEEVENTF_MOVE, dx, dy, 0, 0);
		}

	}

}





QTcpServer* Control::ser;
QHostAddress Control::ip;
int Control::cx;
int Control::cy;
HHOOK Control::mouse;
HHOOK Control::keyboard;
bool Control::esc_down;
bool Control::controling = true;
QTcpSocket* Control::cli = NULL;
Control::Control(QHostAddress  _ip, MainWindow* m)
{
	SetCursorPos(500, 500);
	m_ptr = m;
	ip = _ip;
	ser = new QTcpServer;
	ser->listen(m_ptr->server->serverAddress(), PORT);
	ser->setMaxPendingConnections(10);     //设置监听数量
	connect(ser, SIGNAL(newConnection()), this, SLOT(NewConnection()));      //建立新的连接信号
	connect(ser, SIGNAL(acceptError(QAbstractSocket::SocketError)), this, SLOT(Error(QAbstractSocket::SocketError))); //错误处理

	keyboard = SetWindowsHookExW(WH_KEYBOARD_LL, CallBackProc, GetModuleHandleW(nullptr), 0);
	mouse = SetWindowsHookExW(WH_MOUSE_LL, CallBackProc, GetModuleHandleW(nullptr), 0);
	cx = GetSystemMetrics(SM_CXFULLSCREEN) / 2;
	cy = GetSystemMetrics(SM_CYFULLSCREEN) / 2;
	cout << cx << " " << cy << endl;
	if (keyboard == NULL) {

		qDebug() << "Error Code:" << GetLastError();
	}
	else {


		qDebug() << "挂接成功";

	}
	qDebug() << "控制端已经启动，受控端IP" << ip << endl;
	this->start();
}
void Control::NewConnection()
{
	QTcpSocket* client;     //定义客户端描述符
	client = ser->nextPendingConnection();     //客户端的连接，获取客户端描述符
	qDebug() << "控制：新连接" << client->peerAddress();
	if (client->peerAddress() != ip)
	{
		client->close();
		//TODO:如果不是客户端
	}
	else
	{
		qDebug() << "控制：客户端已经连接";
		cli = client;
	}
	connect(client, SIGNAL(disconnected()), this, SLOT(Disconnected()));
}
void Control::Disconnected()
{
	qDebug() << "客户端已经断开连接！" << endl;
	Quit();
	
}

LRESULT CALLBACK Control::CallBackProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	switch (wParam)
	{
	case WM_KEYDOWN:
	case WM_KEYUP:
	{
		PKBDLLHOOKSTRUCT param = (PKBDLLHOOKSTRUCT)lParam;
		int code = param->vkCode;
		QString ope = wParam == WM_KEYUP ? "up" : "down";
		QString msg = "keyboard " + ope + " " + QString::number(code);
		Send(msg);
		if (code == VK_ESCAPE)//如果是ESC
		{
			if (wParam == WM_KEYDOWN)
			{
				if (esc_down)
				{
					controling = false;
					Quit();
				}
				else
				{
					esc_down = true;
				}
			}
			else if (wParam == WM_KEYUP)
			{
				esc_down = false;
			}
		}
		break;
	}
	case WM_LBUTTONDOWN:
	{
		QString msg = "mouseclick down left";
		Send(msg);
		break;
	}
	case WM_LBUTTONUP:
	{
		QString msg = "mouseclick up left";
		Send(msg);
		break;
	}
	case WM_RBUTTONDOWN:
	{
		QString msg = "mouseclick down right";
		Send(msg);
		break;
	}
	case WM_RBUTTONUP://如果是鼠标左右键，直接转发即可
	{
		QString msg = "mouseclick up right";
		Send(msg);
		break;
	}
	case WM_MOUSEWHEEL://鼠标滚轮事件
	{
		MSLLHOOKSTRUCT* pMhs = (MSLLHOOKSTRUCT*)lParam;
		short z = HIWORD(pMhs->mouseData);
		QString msg = "mousewheel  move " + QString::number(z);
		Send(msg);
		break;
	}
	case WM_MOUSEMOVE:
	{
		MSLLHOOKSTRUCT* pMhs = (MSLLHOOKSTRUCT*)lParam;
		short x = pMhs->pt.x,y = pMhs->pt.y;
		int dx = x - 500, dy = y - 500;
		QString msg = "mousemove  move "+QString::number(dx)+" "+QString::number(dy);
		Send(msg);
	}
	}

	return  1;//返回非0 截获事件
}


void Control::run()
{
	while (controling)
	{
		Sleep(1000);
	}
	qDebug() << "end";

}

void Control::Quit()
{
	ser->close();
	Send("end 0 0");
	UnhookWindowsHookEx(keyboard);
	UnhookWindowsHookEx(mouse);
}
void Control::Send(QString msg)
{
	if (cli != NULL)
	{
		msg += " ";
		//qDebug() << "向" << ip << ":" << PORT << "发送消息:" << msg;
		QByteArray message = msg.toLocal8Bit();
		cli->write(message);
	}
	else
	{
		qDebug() << "客户端未连接，无法发送消息";
	}

}
void Control::Error(QAbstractSocket::SocketError err)
{
	qDebug() << "发送端出错" << err << endl;
}


